﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Daan;
using DanMuGame;
using GlmUnity;
using System.Threading;
using System.Threading.Tasks;
using UnityEngine.UI;
using System;

public class Main : Manager<Main>
{
    public enum State
    {
        Connecting,//等待连接到弹幕服务器
        Initializing,//等待AI生成基础的必备内容
        SubmitingWord,//提交词中
        SelectingTeam,//选择队伍中
        Battling,//AI生成战斗结果中,
        Settling,//结算中，等待主播自己进入下一句
    }
    public State state = State.Connecting;
    public int level;
    public Dictionary<string, Player> playerDict = new Dictionary<string, Player>();
    [SerializeField] public List<Player> alivePlayerList = new List<Player>();
    public List<Level> levelList;

    public Transform lobbyParent;
    public Transform levelParent;

    private List<PlayerItem> questionAreaList = new List<PlayerItem>();
    public List<Team> teamList = new List<Team>();

    public Text tipTxt;

    public StoryResultPanel resultPanel;

    public float[] time;
    // Start is called before the first frame update
    async void Start()
    {
        this.questionAreaList = new List<PlayerItem>(this.lobbyParent.GetComponentsInChildren<PlayerItem>());
        this.tipTxt.text = "等待连接弹幕服务器...";
        Message.SendMessage(Message.SystemHints.Connecting);
        Message.Main.AddListener(Message.CommonCmd.GameStart, (data) =>
         {
             this.InitLevel();
         });
        DanmuCommandManager.Instance.talkCommand = (id, content, count) =>
        {
            return false;
        };

        DanmuCommandManager.Instance.AddContainsCommand("加入", (id, content, count) =>
        {
            var player = this.playerDict.TryGet(id);
            if (player != null)
            {
                Debug.LogError("重开一局了，怎么会有玩家啊");
                return false;
            }
            //不在流程内不能给词
            if (this.state != State.Initializing) return false;

            var user = UserManager.Instance.GetUser(id);
            var boo = this.JoinPlayer(id, user.nickname);
            if (boo)
            {
                this.questionAreaList[player.area].gameObject.SetActive(true);
                this.questionAreaList[player.area].ShowQuestion();
                Debug.Log($"{user.nickname}加入了游戏");
            }
            return false;
        });

        DanmuCommandManager.Instance.AddContainsCommand("给词=", (id, content, count) =>
        {
            var player = this.playerDict.TryGet(id);
            //没加入的玩家不能选阵营
            if (player == null) return false;

            //不在流程内不能给词
            if (this.state != State.SubmitingWord) return false;

            //死亡的人不能给词
            if (player.state == Player.State.Dead) return false;


            var str = content.Replace(" ", "").Split("=");
            if (str.Length != 2) return false;
            if (str[1].Length > 5) return false;

            this.SubmitWord(id, str[1]);
            return false;
        });

        DanmuCommandManager.Instance.AddContainsCommand("剧情=", (id, content, count) =>
        {
            var player = this.playerDict.TryGet(id);
            //没加入的玩家不能选阵营
            if (player == null) return false;

            //不在流程内不能给词
            if (this.state != State.SelectingTeam) return false;

            //死亡的人不能选阵营
            if (player.state == Player.State.Dead) return false;


            var str = content.Replace(" ", "").Split("=");
            if (str.Length != 2) return false;
            var index = str[1].ToInt(-1);
            if (index == -1 || index >= this.teamList.Count) return false;
            index = index - 1;
            var team = this.teamList[index];
            if (team.playerList.Count < team.max)
            {
                player.team = index;
                team.playerList.Add(player);
            }
            return false;
        });
    }


    // Update is called once per frame
    void Update()
    {

    }

    #region 玩家相关

    public bool JoinPlayer(string id, string name, bool isFake = false)
    {
        if (this.playerDict.Count >= 16) return false;
        var player = new Player(name, isFake)
        {
            id = id,
        };

        player.area = this.alivePlayerList.Count;
        this.questionAreaList[player.area].gameObject.SetActive(true);
        this.questionAreaList[player.area].Clear();
        this.questionAreaList[player.area].SetPlayer(player);
        this.alivePlayerList.Add(player);
        this.playerDict.Add(id, player);

        return true;
    }

    public void JoinFakePlayer()
    {
        var left = 16 - this.alivePlayerList.Count;
        for (int i = 0; i < left; i++)
        {
            var name = $"电脑{i + 1}";
            this.JoinPlayer(name, name, true);
        }
    }
    #endregion


    #region 流程控制

    public void NextLevel()
    {
        this.level++;
        for (int i = 0; i < this.levelList.Count; i++)
        {
            this.levelList[i].gameObject.SetActive(i == this.level);
        }


        for (int i = 0; i < 4; i++)
        {
            AIAgentManager.Instance.Get($"说书人{i}").Clear();
        }


    }

    public Button nextLevelBtn;
    public Button confirmStoryBtn;

    /// <summary>
    /// 确认剧情按钮
    /// </summary>
    public void BtnConfirmTeam()
    {
        if (this.state != State.SelectingTeam) return;
        this.MakeRandomTeam();
        this.tipTxt.text = $"剧情选择完成";
        this.WaitForGenStory();

    }

    public void BtnShowBattleResult(int index)
    {
        var team = this.teamList[index];
        var info = team.info;

        this.resultPanel.SetContent(info.result);
    }

    /// <summary>
    /// 下一关按钮
    /// </summary>
    public void BtnNextLevel()
    {
        this.WaitForSubmitWord();
    }

    public void InitLevel()
    {
        this.level = -1;

        this.state = State.Initializing;
        this.tipTxt.text = "等待AI初始化...";


        this.lobbyParent.gameObject.SetActive(true);
        this.lobbyParent.SetActiveAllChildren(false);
        this.levelParent.gameObject.SetActive(false);

        Timer.Register(this.time[0], () =>
        {
            this.JoinFakePlayer();
            this.WaitForSubmitWord();
        }, (t) =>
        {
            this.tipTxt.text = $"输入 {"加入".AddColorTag(Color.green)} 以加入游戏！\n({this.alivePlayerList.Count} / 16)\n({(int)(30 - t)}秒)";
        });
    }

    public void WaitForSubmitWord()
    {
        if (this.state != State.Settling && this.state != State.Initializing) return;
        if (this.level == 4) return;
        this.NextLevel();

        for (int i = 0; i < this.alivePlayerList.Count; i++)
        {
            var player = this.alivePlayerList[i];
            this.questionAreaList[player.area].gameObject.SetActive(player.state == Player.State.Alive);
        }

        this.lobbyParent.gameObject.SetActive(true);
        this.levelParent.gameObject.SetActive(false);

        this.state = State.SubmitingWord;




        var step = 2;
        {
            void next()
            {
                this.tipTxt.text = $"收集关键词完毕";
                this.SubmitWordTimeout();
                Timer.Register(2f, this.WaitForSelectTeam);
            }
            this.RandomQuestion(() =>
            {
                step--;
                if (step == 0)
                    next();
            });

            //把所有问题都显示出来吧
            for (int i = 0; i < this.alivePlayerList.Count; i++)
            {
                var area = this.questionAreaList[this.alivePlayerList[i].area];
                area.ShowQuestion();
                area.ShowAllWord();
            }

            Timer.Register(this.time[1], () =>
            {
                step--;
                if (step == 0)
                {
                    next();
                }
                else
                {
                    this.tipTxt.text = $"等待AI生成随机词";
                }
            }, (t) =>
            {
                this.tipTxt.text = $"输入【给词=xx】来提供词！\n({(int)(30 - t)}秒)";
            });
        }
    }

    public void WaitForSelectTeam()
    {
        this.lobbyParent.gameObject.SetActive(false);
        this.levelParent.gameObject.SetActive(true);

        this.confirmStoryBtn.gameObject.SetActive(true);
        this.nextLevelBtn.gameObject.SetActive(false);

        for (int i = 0; i < this.alivePlayerList.Count; i++)
        {
            this.alivePlayerList[i].team = -1;
        }
        var liveCount = this.alivePlayerList.FindAll(t => t.state == Player.State.Alive).Count;
        var teamCount = this.levelList[this.level].panelList.Count;
        Debug.Log($"{liveCount}个人将分为{this.levelList[this.level].panelList.Count}个队伍进行决斗！");
        {
            this.teamList = new List<Team>();
            int left = liveCount % teamCount;
            int per = liveCount / teamCount;
            for (int i = 0; i < teamCount; i++)
            {
                var team = new Team();
                {
                    team.index = i;
                    team.max = per;
                }
                this.teamList.Add(team);
            }

            for (int i = 0; i < left; i++)
            {
                this.teamList.GetRandom().max++;
            }
        }

        this.state = State.SelectingTeam;
        this.tipTxt.text = $"输入【剧情=序号】\n来选择你想演绎的剧情！(如：剧情=1))";
    }



    public Color wordColor;
    public Color nicknameColor;
    public void WaitForGenStory()
    {
        this.confirmStoryBtn.gameObject.SetActive(false);
        this.nextLevelBtn.gameObject.SetActive(false);

        this.state = State.Battling;
        this.tipTxt.text = $"正在演绎剧情...";
        var step = this.teamList.Count;
        for (int i = 0; i < this.teamList.Count; i++)
        {
            var team = this.teamList[i];
            this.GenTeamStoryTemplate(team, this.levelList[this.level].deadCount);
            var index = i;
            AIAgentManager.Instance.Get($"说书人{index}").Excute(team.info.storyOutput, (data) =>
            {
                step--;
                team.info.result = data.content;

                for (int i = 0; i < team.allWordsList.Count; i++)
                {
                    team.info.result = team.info.result.Replace($"[{team.allWordsList[i]}]", team.allWordsList[i].AddColorTag(this.wordColor));
                }

                for (int i = 0; i < team.playerList.Count; i++)
                {
                    team.info.result = team.info.result.Replace($"[{team.playerList[i].nickname}]", team.playerList[i].nickname.AddColorTag(this.nicknameColor));
                }

                if (step == 0)
                {
                    this.state = State.Settling;
                    this.tipTxt.text = $"剧情演绎完成！";

                    this.nextLevelBtn.gameObject.SetActive(true);
                }


                //var str = string.Format(this.transform.Find<Text>("说书人2").text, team.info.answerInput);
                //AIAgentManager.Instance.Get($"说书人{index}").Excute(str, (data2) =>
                //{
                //    step--;
                //    team.info.result = data2.content;

                //    for (int i = 0; i < team.allWordsList.Count; i++)
                //    {
                //        team.info.result = team.info.result.Replace($"[{team.allWordsList[i]}]", team.allWordsList[i].AddColorTag(this.wordColor));
                //    }

                //    for (int i = 0; i < team.playerList.Count; i++)
                //    {
                //        team.info.result = team.info.result.Replace($"[{team.playerList[i].nickname}]", team.playerList[i].nickname.AddColorTag(this.nicknameColor));
                //    }

                //    if (step == 0)
                //    {
                //        this.state = State.Settling;
                //        this.tipTxt.text = $"剧情演绎完成！";

                //        this.nextLevelBtn.gameObject.SetActive(true);
                //    }
                //});
            });
        }
    }
    #endregion



    public void RandomQuestion(Action endCall)
    {
        LevelConfig.questionRandomList.ResetCache();

        var list = new List<string>();
        for (int i = 0; i < this.alivePlayerList.Count; i++)
        {
            this.alivePlayerList[i].randomAnswer = "";
            var question = LevelConfig.questionRandomList.GetRandom(repeat: false);
            this.alivePlayerList[i].questions.Add(question);
            list.Add(question);
        }

        var str = string.Join("\n", list);

        AIAgentManager.Instance.Get($"出词人").Excute(str, (data) =>
        {
            Debug.Log(data.content);
            var answerList = new List<string>(data.content.Replace(" ", "").Split('|'));
            for (int i = 0; i < list.Count; i++)
            {
                Debug.Log($"{list[i]} : {answerList[i]}");
                this.alivePlayerList[i].randomAnswer = answerList[i];
            }

            endCall();
        });
    }

    public void SubmitWordTimeout()
    {
        for (int i = 0; i < this.alivePlayerList.Count; i++)
        {
            this.SubmitRandomWord(this.alivePlayerList[i].id);
        }
    }

    /// <summary>
    /// 超时或是AI的情况下，会自动随机一个词给他
    /// </summary>
    public void SubmitRandomWord(string id)
    {
        var player = this.playerDict.TryGet(id);
        this.SubmitWord(id, player.randomAnswer == "" ? "随机" : player.randomAnswer);
    }

    public void SubmitWord(string id, string word)
    {
        var player = this.playerDict.TryGet(id);
        if (player == null) return;
        if (player.answer.Count >= this.level + 1) return;
        player.answer.Add(word);
        this.questionAreaList[player.area].ShowQuestion();
    }

    /// <summary>
    /// 把超时或AI玩家随机分配到队伍里
    /// </summary>
    /// <param name="teamCount"></param>
    /// <returns></returns>
    public void MakeRandomTeam()
    {
        var list = new List<Player>(this.alivePlayerList);
        for (int i = 0; i < this.alivePlayerList.Count; i++)
        {
            if (this.alivePlayerList[i].team != -1 || this.alivePlayerList[i].state == Player.State.Dead)
            {
                list.Remove(this.alivePlayerList[i]);
            }
        }
        while (list.Count > 0)
        {
            var boo = false;
            for (int i = 0; i < this.teamList.Count; i++)
            {
                var team = this.teamList[i];
                if (team.playerList.Count < team.max)
                {
                    var player = list.GetRandom(true);
                    player.team = team.index;
                    team.playerList.Add(player);
                    boo = true;
                    continue;
                }
            }
            if (!boo)
            {
                Debug.LogError("怎么可能分不动啊？");
                break;
            }
        }
        for (int i = 0; i < this.teamList.Count; i++)
        {
            var levelData = this.levelList[this.level];
            var panel = levelData.panelList[i];
            for (int j = 0; j < this.teamList[i].playerList.Count; j++)
            {
                var player = this.teamList[i].playerList[j];
                panel.AddPlayer(player);
            }
        }


    }

    public class StoryInfo
    {
        public string questionInput;
        public string answerInput;
        public string playerInput;
        public string storylineInput;
        public string themeInput;
        public string storyOutput;

        public string result;
    }

    /// <summary>
    /// 生成队伍的模板
    /// </summary>
    /// <param name="team"></param>
    /// <param name="winnerCount"></param>
    /// <returns></returns>
    public StoryInfo GenTeamStoryTemplate(Team team, int deadCount)
    {
        team.info = new StoryInfo();
        //陈列所有的词汇
        team.info.questionInput = team.GetAllQuestion();
        team.info.answerInput = team.GetAllQuestionAndAnswer();
        team.GenWinner(deadCount);
        var list = new List<string>();
        var list2 = new List<string>();
        team.info.playerInput = "";
        {

            foreach (var player in team.playerList)
            {
                if (team.winPlayerList.Contains(player))
                {
                    list.Add($"{player.nickname}");
                }
                else
                {
                    list.Add($"{player.nickname}");
                    list2.Add($"{player.nickname}");
                    player.state = Player.State.Dead;
                }
            }

            team.info.playerInput = string.Join("\n", list);
        }

        team.info.storylineInput = LevelConfig.GenStoryline(1);


        team.info.themeInput = this.levelList[this.level].panelList[team.index].inputField.text;

        team.info.storyOutput = string.Format(this.transform.Find<Text>("说书人").text, team.info.answerInput, team.info.playerInput, string.Join("\n", list2),team.info.themeInput, team.info.storylineInput, team.playerList.Count * 100 + (this.level + 1) * 100);
        Debug.Log(team.info.storyOutput);
        return team.info;
    }

}
